package main

import (
	"fmt"
)

type Person struct {
	name string
	age  int
}
type PersonHander interface {
	Batch(origs <-chan Person) <-chan Person
	Hander(p Person)
}

type PersonHanderTmp struct{}

var personNum int = 10
var persons []Person = make([]Person, personNum)

func init() {
	for i := 0; i < personNum; i++ {
		n := fmt.Sprintf("%s%d", "Person", i)
		p := Person{name: n, age: i}
		persons[i] = p
	}
	fmt.Printf("all person has inited\n")
}
func main() {
	hander := getPersonHander()
	origs := make(chan Person, 100)
	dest := hander.Batch(origs)
	go fetchPerson(origs)
	sign := savePerson(dest)
	<-sign
}

//向通道中写入人员信息
func fetchPerson(origs chan<- Person) {
	for _, p := range persons {
		origs <- p
	}
	close(origs) // must close the channel when finish send data
}

func savePerson(dest <-chan Person) chan byte {
	sign := make(chan byte, 2)
	go func() {
		for {
			p, ok := <-dest
			if !ok {
				sign <- 1
				break
			}
			savePersonHander(p)
		}
	}()
	return sign
}

//按批次处理人员信息
func (hander PersonHanderTmp) Batch(origs <-chan Person) <-chan Person {
	dest := make(chan Person, 100)
	go func() {
		for {
			p, ok := <-origs
			if !ok {
				close(dest) // must close the channel when finish send data
				break
			}
			hander.Hander(p)
			dest <- p
		}
	}()
	return dest
}

func (Hander PersonHanderTmp) Hander(p Person) {
	fmt.Printf("Person %s has chosen\n", p.name)
}

//获取一个处理模块
func getPersonHander() PersonHander {
	hander := new(PersonHanderTmp)
	return hander
}

func savePersonHander(p Person) {
	fmt.Printf("saved person is:%s,age :%d\n", p.name, p.age)

}
